#include <iostream>
#include "opencv2/opencv.hpp"
#include "preprocess2.h"
#include "plateJudge.h"
#include "CCharacter.h"

using namespace std;
using namespace cv;

#define PROCESS_IMAGE_LENGTH 160
#define LENGTH_ERROR 1
#define TOO_SMALL -1
#define WRITE_FLAG false

int fPreprocessImage(Mat Pre_src_image, int src_image_length, Mat &dest_image, bool debug)
{
	if(src_image_length - PROCESS_IMAGE_LENGTH < -LENGTH_ERROR){
		cout << "the plate pixs is too small to process" << endl;
		return TOO_SMALL;
	}
	else if(src_image_length - PROCESS_IMAGE_LENGTH > LENGTH_ERROR){
		cout << "the plate pixs is too big, resize it" << endl;
		float scale = float(PROCESS_IMAGE_LENGTH)/float(src_image_length);
		resize(Pre_src_image, dest_image, Size(), scale, scale, CV_INTER_AREA);
	}
	else{
		cout << "the plate pixs is fitable" << endl;
		dest_image = Pre_src_image;
	}
	
	if(debug == true){
		imshow("Pre_src_image", Pre_src_image);
		waitKey(0);
		destroyWindow("dest_image");
		
		imshow("dest_image", dest_image);
		waitKey(0);
		destroyWindow("dest_image");
	}
	if (WRITE_FLAG) {
		std::stringstream ss(std::stringstream::in | std::stringstream::out);
		ss << "./tmp" << "/" << __FUNCTION__ << ".jpg";
		imwrite(ss.str(), dest_image);
	}

	return 0;
}

Mat fPreprocessImage2(const Mat &preSrcImage, Point tl, Size pLateRegionSize, bool debug)
{
	Mat destImage;
	if(tl.x < 0 || tl.y <0 || tl.x + pLateRegionSize.width > preSrcImage.cols || tl.y + pLateRegionSize.height > preSrcImage.rows){
		cout << "input parameters not right" << endl;
		return Mat();
	}
	destImage = preSrcImage(Rect(tl.x, tl.y, pLateRegionSize.width, pLateRegionSize.height));
	if(debug == true){
		imshow("destImage", destImage);
		waitKey(0);
		destroyWindow("destImage");
	}
	if (WRITE_FLAG) {
		std::stringstream ss(std::stringstream::in | std::stringstream::out);
		ss << "./tmp" << "/" << __FUNCTION__ << ".jpg";
		imwrite(ss.str(), destImage);
	}
	return destImage;
}

int resizeAndCut(Mat &Pre_src_image, Mat &dImage, PLATESIZE levelTwo, bool debug)
{
	int sizeX = 812, sizeY = 513;
    int tlX = 457, tlY = 113;
	if(levelTwo == MIDDLE){
		Mat dest_image;
        fPreprocessImage(Pre_src_image, 190, dest_image, false);//190 236
        if(debug == true)
            imwrite("./resize1.jpg", dest_image);
        
        Pre_src_image = dest_image;
        sizeX = 878;
        sizeY = 354;
        tlX = 132;
        tlY = 180;
	}
    else if(levelTwo == BIG){
        Mat dest_image;
        fPreprocessImage(Pre_src_image, 236, dest_image, false);//190 236
        if(debug == true)
            imwrite("./resize2.jpg", dest_image);
        
        Pre_src_image = dest_image;
        sizeX = 809;
        sizeY = 224;
        tlX = 34;//809
        tlY = 243;//224
    }

	Size pLateRegionSize(sizeX, sizeY);
	Point tl(tlX, tlY);
	dImage = fPreprocessImage2(Pre_src_image, tl, pLateRegionSize, false);

    return 0;
}
/*
int main(int argc, char **argv)
{
	
	int src_image_length = 278;
	Mat Pre_src_image;
	Mat dest_image;
	bool debug = false;
	Pre_src_image = imread("./test_preprocess.jpg");
	fPreprocessImage(Pre_src_image, src_image_length, dest_image, debug);
	
	//Mat preSrcImage = imread("./test_preprocess.jpg");
	Size pLateRegionSize(1455, 679);
	Point tl(229, 383);
	Mat dest_image2;
	bool debug = false;
	dest_image2 = fPreprocessImage2(dest_image, tl, pLateRegionSize, debug);

    return 0;
}
*/

int preprocessPlate(Plate &srcPlate, bool ifResize)
{
    Mat dest;
    deleteNotArea(srcPlate.plateMat, BLUE);
    if((srcPlate.fMser == true) && (ifResize == true)){
        Mat inMat = srcPlate.plateMat;
        int w = inMat.cols;
	    int h = inMat.rows;
    	Mat tmpmat = inMat(Rect_<double>(w * 0.04, h * 0.06, w * 0.92, h * 0.84));
    	resize(tmpmat, dest, Size(inMat.size()));
    }
    else
        dest = srcPlate.plateMat;
    srcPlate.plateMat = dest;
    return 0;
}

